<template>
  <div class="upload-card">
    <label for="upload-card-file-input">
      <div class="upload-image-wrap overlay">
        <!-- <img v-if="image" class="image" :src="image" alt="" /> -->
        <canvas v-show="image" ref="paintDomRef" :class="[image && 'image']" width="970" height="616"></canvas>
        <div class="upload-handle">
          <i class="iconfont icon-image-fill"></i>
          <div>{{ image ? '替换图片' : '上传图片' }}</div>
          <p>支持大小不超过 2MB的PNG、JPG、JPEG文件</p>
        </div>
      </div>
    </label>
    <input id="upload-card-file-input" type="file" style="display: none" @change="onFileChange" />
  </div>
</template>

<script setup lang="ts">
  import { message } from 'ant-design-vue'
  import { onMounted, onUnmounted, ref, watch } from 'vue'

  import { useFileVerify } from '@/hooks/use-file-verify'
  import { DmpImgBasicPaint } from '@/utils/dmp-paint'

  export interface ResultOptions {
    id: string
    label: string
    value: string | number
    box: number[]
  }

  export interface ResultCardProps {
    // 结果列表
    resultList: ResultOptions[]
  }
  const props = withDefaults(defineProps<ResultCardProps>(), {})

  const emits = defineEmits<{
    (e: 'onFileChange', file: File): void
  }>()

  const paintDomRef = ref<HTMLCanvasElement>()
  const dmpPaint = new DmpImgBasicPaint()
  onMounted(async () => {
    dmpPaint.init(paintDomRef.value as HTMLCanvasElement)
  })

  /* 绘制标注图形 */
  const drawObjectToCanvas = (item: ResultOptions) => {
    if (!item?.box?.length) return
    const box = [
      {
        x: item.box[0],
        y: item.box[1]
      },
      {
        x: item.box[2],
        y: item.box[3]
      }
    ]
    dmpPaint.drawObjectToCanvas({
      uid: item.id,
      type: 'rect',
      points: box,
      color: 'rgba(24, 104, 233, 1)'
    })
  }

  const stopWatchProps = watch(
    () => props.resultList,
    newVal => {
      dmpPaint.clearMarkObjList()
      newVal.forEach(item => {
        drawObjectToCanvas(item)
      })
    }
  )

  const image = ref('')
  const { basicVerify } = useFileVerify({
    suffix: 'png,jpg,jpeg',
    size: 2,
    nameByteLength: 200
  })
  const onFileChange = async (e: any) => {
    const file = e.target.files[0]
    const result = basicVerify(file)
    e.target.value = ''
    if (result.code !== 'success') {
      return message.error(result.message)
    }
    dmpPaint.clearCanvas()
    image.value = URL.createObjectURL(file)
    await dmpPaint.loadImage(image.value)
    emits('onFileChange', file)
  }

  onUnmounted(() => {
    stopWatchProps()
  })
</script>

<style lang="less" scoped>
  .upload-card {
    padding: 24px;
    width: 100%;
    height: 100%;

    .upload-image-wrap {
      position: relative;
      overflow: hidden;
      width: 100%;
      height: 100%;

      .image {
        width: 100%;
        height: 100%;
        background: #f2f3f5;
        border-radius: 4px;
        object-fit: contain;
      }

      .upload-handle {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
        border: 2px dashed #e8e9eb;
        border-radius: 4px;
        flex-direction: column;
        gap: 12px 0;
        cursor: pointer;

        > i {
          font-size: 28px;
        }

        > div {
          display: flex;
          justify-content: center;
          align-items: center;
          padding: 7px 16px;
          height: 36px;
          font-size: 14px;
          color: rgba(17, 22, 31, 0.75);
          background: rgba(0, 0, 0, 0.03);
          border-radius: 6px;
          font-weight: 400;
          line-height: 22px;
        }

        > p {
          position: relative;
          top: 218px;
          font-size: 14px;
          text-align: center;
          color: rgba(17, 22, 31, 0.29);
          font-weight: 400;
        }
      }

      &:has(.image) {
        cursor: pointer;

        .upload-handle {
          display: none;
          border: none;
        }

        &:hover {
          .upload-handle {
            display: flex;

            > i {
              color: rgba(255, 255, 255, 0.95);
            }

            > div {
              color: #fff;
              background: rgba(255, 255, 255, 0.1);
            }

            > p {
              color: rgba(255, 255, 255, 0.95);
            }
          }

          &.overlay {
            &::after {
              position: absolute;
              top: 0;
              left: 0;
              width: 100%;
              height: 100%;
              background: rgba(0, 0, 0, 0.25);
              border-radius: 4px;
              content: '';
            }
          }
        }
      }
    }
  }
</style>
